from django.db import transaction
from django.db.models import Sum
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from BYD_ERP.utils.get_inventory import get_inventory_by_goods
from sale_info.models import SaleOrderItemModel, SaleOrderModel
from warehouse_info.models import OutStorageItemModel


class SaleOrderItemSerializer(serializers.ModelSerializer):
    """
        销售订单项目的序列化器
    """
    # cur_inventory这个属性只是用于查询（就是序列化），所以加上read_only=True
    cur_inventory = serializers.SerializerMethodField(read_only=True, label='当前仓库中的库存')
    # 已经出库的数量：某种货品在当前销售订单中的出库数量
    already_out_number = serializers.SerializerMethodField(read_only=True, label='当前已经出库的数量')

    class Meta:
        model = SaleOrderItemModel
        fields = '__all__'

    def get_cur_inventory(self, obj):
        # 当前obj是：SaleOrderItemModel对象
        result = get_inventory_by_goods(obj.goods.id, obj.warehouse.id)
        # 如果result有就返回result，如果result没有就返回0。
        return result if result else 0

    # sale_order销售订单的状态，0：未审核，1：已审核，2：部分出库，3：全部出库，4：收取定金，5：完成销售

    # 已经出库的数量
    def get_already_out_number(self, obj):
        if obj.sale_order.status == '0' or obj.sale_order.status == '1':
            # 如果销售订单还没有出库，就不用查了，直接返回0
            return 0
        else:
            # 先根据销售订单的ID作为第一个过滤条件，基于当前货品ID作为第二个过滤条件，而且出库单状态不是0未审核
            out_count = OutStorageItemModel.objects.filter(out_storage__sale_order__id=obj.sale_order.id,
                                                           goods_id=obj.goods.id).exclude(
                out_storage__status='0').aggregate(sum=Sum('out_count'))
            if out_count:
                return out_count['sum'] if out_count['sum'] else 0
            return 0


class SaleOrderSerializer(serializers.ModelSerializer):
    """
        新增和修改销售订单的序列化和反序列化
    """
    # write_only=True表示只是用于反序列化
    item_list = SaleOrderItemSerializer(many=True)
    # goods_info只是在序列化的时候用到，所以需要加上read_only=True
    # 销售订单列表中需要展示：商品信息，多个商品的名称+规格，中间使用逗号隔开
    goods_info = serializers.SerializerMethodField(read_only=True, label='包含销售订单中每个商品信息')

    class Meta:
        model = SaleOrderModel
        fields = '__all__'

    def get_goods_info(self, obj):
        """
            商品信息：商品1名称+商品1规格，商品2名称+商品2规格，…………
        """
        # 使用.all()返回的是列表
        if obj.item_list.all():
            result = []
            for item in obj.item_list.all():
                result.append(item.name + (item.specification if item.specification else ''))
            return ','.join(result)
        return ''

    def create(self, validated_data):
        item_list = validated_data.pop('item_list')
        with transaction.atomic():
            sale = SaleOrderModel.objects.create(**validated_data)
            print('-------------------')
            print(sale)
            for item in item_list:
                sim = SaleOrderItemModel.objects.create(sale_order=sale, **item)
                goods = item.get('goods')
                sim.name = goods.name
                sim.specification = goods.specification
                sim.model_number = goods.model_number
                sim.save()
        return sale

    def update(self, instance, validated_data):
        # instance：正在修改的销售订单
        if instance.status != '0':
            # sale_order销售订单的状态，0：未审核，1：已审核，2：部分出库，3.全部出库，4：已付定金，5：完成销售（货全部出库，付全款完成）
            raise ValidationError('销售订单已经生效，不能修改')
        item_list = validated_data.pop('item_list')
        # 如果之前有老数据（之前新增的销售订单项目数据）是需要删除掉的
        old_list = instance.item_list.all()
        with transaction.atomic():
            if old_list.exists():
                # 把老数据删除
                old_list.delete()
            for item in item_list:
                sim = SaleOrderItemModel.objects.create(sale_order=instance, **item)
                goods = item.get('goods')
                sim.name = goods.name
                sim.specification = goods.specification
                sim.model_number = goods.model_number
                sim.units = goods.units
                sim.units_name = goods.units_name
                sim.save()
            result = super(SaleOrderSerializer, self).update(instance=instance, validated_data=validated_data)
        return result


class SaleOrderGetSerializer(serializers.ModelSerializer):
    """
        仅仅用于查询展示销售订单详情的序列化器
    """
    item_list = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = SaleOrderModel
        fields = '__all__'

    def get_item_list(self, obj):
        result = []  # 返回的是列表，列表中是多个字典
        if obj.item_list.all().exists():
            for item in obj.item_list.all():
                # item是一个SaleOrderItemModel的对象
                # 有一部分信息在SaleOrderItemModel里面没有
                # 只有在GoodsModel里面有：开票名称、开票型号、长度等
                item_dict = {}
                goods = item.goods
                warehouse = item.warehouse
                item_dict['goods'] = goods.id
                item_dict['name'] = goods.name  # 国标名称
                item_dict['specification'] = goods.specification  # 件号
                item_dict['model_number'] = goods.model_number  # 型号
                item_dict['length'] = goods.length
                item_dict['brand'] = goods.brand  # 品牌
                item_dict['units'] = goods.units.basic_name
                item_dict['sales_count'] = item.sales_count
                item_dict['sales_price'] = item.sales_price
                item_dict['sales_money'] = item.sales_money
                item_dict['remark'] = item.remark
                # 该商品的总库存数量
                item_dict['cur_inventory_total'] = get_inventory_by_goods(goods.id)
                item_dict['cur_inventory_peitao'] = get_inventory_by_goods(goods.id, warehouse_id=1)

                result.append(item_dict)
        return result
